package org.example.juc.question;

import java.util.concurrent.atomic.AtomicInteger;

public class PrintFoobarAlternatelySolution {
    private int n;
    private volatile AtomicInteger num = new AtomicInteger(0);

    public static void main(String[] args) {
        PrintFoobarAlternatelySolution solution = new PrintFoobarAlternatelySolution(5);
        Runnable printFoo = new Runnable() {
            @Override
            public void run() {
                System.out.println("foo");
            }
        };
        Thread thread1 = new Thread(()-> {
            try {
                solution.foo(printFoo);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        Runnable printBar = new Runnable() {
            @Override
            public void run() {
                System.out.println("bar");
            }
        };
        Thread thread2 = new Thread(()-> {
            try {
                solution.bar(printBar);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
        thread1.start();
        thread2.start();
        try {
            thread1.join();
            thread2.join();
        } catch (Exception e) {
            System.out.println(e);
        }
        System.out.println("Main thread finished.");
    }

    public PrintFoobarAlternatelySolution(int n) {
        this.n = n;
    }
    public void foo(Runnable printFoo) throws InterruptedException {

        synchronized (this) {
            for (int i = 0; i < n; i++) {
                while (num.get() % 2 != 0) {
                    wait();
                };
                // printFoo.run() outputs "foo". Do not change or remove this line.
                printFoo.run();
                num.incrementAndGet();
                notify();
            }
        }
    }

    public void bar(Runnable printBar) throws InterruptedException {

        synchronized (this) {
            for (int i = 0; i < n; i++) {
                while (num.get() % 2 == 0) {
                    wait();
                };
                // printBar.run() outputs "bar". Do not change or remove this line.
                printBar.run();
                num.incrementAndGet();
                notify();
            }
        }
    }
}
